/*!
 * \file WtDataReader.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief WonderTrader数据读取器头文件
 * 
 * \details 该文件定义了WtDataReader数据读取器类，是WonderTrader数据存储系统的核心组件：
 *          - 实现IDataReader接口，提供统一的数据读取服务
 *          - 支持实时数据和历史数据的读取
 *          - 支持多种数据类型：K线、Tick、成交明细、委托明细、委托队列
 *          - 使用内存映射文件技术提高数据访问效率
 *          - 支持数据缓存机制，优化重复读取性能
 *          - 支持股票复权因子处理
 *          - 支持期货主力合约连续数据处理
 */
#pragma once
#include <string>
#include <stdint.h>

#include "DataDefine.h"

#include "../Includes/FasterDefs.h"
#include "../Includes/IDataReader.h"

#include "../Share/BoostMappingFile.hpp"

NS_WTP_BEGIN

typedef std::shared_ptr<BoostMappingFile> BoostMFPtr; ///< 内存映射文件智能指针类型定义

/*!
 * \class WtDataReader
 * \brief WonderTrader数据读取器类
 * 
 * \details 数据读取器是WonderTrader数据存储系统的核心组件，主要功能包括：
 *          - 实时数据读取：支持当前交易日的实时K线、Tick、Level2数据读取
 *          - 历史数据读取：支持历史K线、Tick、Level2数据的批量读取
 *          - 数据缓存管理：使用内存映射文件和缓存机制提高访问效率
 *          - 复权处理：支持股票数据的前复权、后复权处理
 *          - 主力合约：支持期货主力合约的连续数据生成
 *          - 多周期支持：支持1分钟、5分钟、日线等多个时间周期
 *          - 外部加载器：支持通过外部数据加载器加载数据
 */
class WtDataReader : public IDataReader
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * 初始化数据读取器，设置默认参数
	 */
	WtDataReader();
	
	/*!
	 * \brief 析构函数
	 * 
	 * 清理资源，关闭文件映射
	 */
	virtual ~WtDataReader();

private:
	/*!
	 * \struct RTKlineBlockPair
	 * \brief 实时K线数据块配对结构体
	 * 
	 * \details 用于管理实时K线数据块的结构体，包含：
	 *          - 数据块指针：指向实际的K线数据块
	 *          - 文件映射：内存映射文件的智能指针
	 *          - 容量记录：记录最后的数据容量，用于检测数据更新
	 */
	typedef struct _RTKBlockPair
	{
		RTKlineBlock*	_block;		///< K线数据块指针
		BoostMFPtr		_file;		///< 内存映射文件智能指针
		uint64_t		_last_cap;	///< 最后容量记录

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_RTKBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
		}

	} RTKlineBlockPair;
	typedef faster_hashmap<std::string, RTKlineBlockPair>	RTKBlockFilesMap; ///< 实时K线数据块映射表

	/*!
	 * \struct TickBlockPair
	 * \brief Tick数据块配对结构体
	 * 
	 * \details 用于管理实时Tick数据块的结构体，包含：
	 *          - 数据块指针：指向实际的Tick数据块
	 *          - 文件映射：内存映射文件的智能指针
	 *          - 容量记录：记录最后的数据容量，用于检测数据更新
	 */
	typedef struct _TBlockPair
	{
		RTTickBlock*	_block;		///< Tick数据块指针
		BoostMFPtr		_file;		///< 内存映射文件智能指针
		uint64_t		_last_cap;	///< 最后容量记录

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_TBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
		}
	} TickBlockPair;
	typedef faster_hashmap<std::string, TickBlockPair>	TBlockFilesMap; ///< Tick数据块映射表

	/*!
	 * \struct TransBlockPair
	 * \brief 逐笔成交数据块配对结构体
	 * 
	 * \details 用于管理实时逐笔成交数据块的结构体，包含：
	 *          - 数据块指针：指向实际的成交数据块
	 *          - 文件映射：内存映射文件的智能指针
	 *          - 容量记录：记录最后的数据容量
	 *          - 文件流：用于数据写入的文件流
	 */
	typedef struct _TransBlockPair
	{
		RTTransBlock*	_block;		///< 成交数据块指针
		BoostMFPtr		_file;		///< 内存映射文件智能指针
		uint64_t		_last_cap;	///< 最后容量记录

		std::shared_ptr< std::ofstream>	_fstream;	///< 文件输出流智能指针

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_TransBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
		}
	} TransBlockPair;
	typedef faster_hashmap<std::string, TransBlockPair>	TransBlockFilesMap; ///< 成交数据块映射表

	/*!
	 * \struct OrdDtlBlockPair
	 * \brief 逐笔委托数据块配对结构体
	 * 
	 * \details 用于管理实时逐笔委托数据块的结构体，包含：
	 *          - 数据块指针：指向实际的委托明细数据块
	 *          - 文件映射：内存映射文件的智能指针
	 *          - 容量记录：记录最后的数据容量
	 *          - 文件流：用于数据写入的文件流
	 */
	typedef struct _OdrDtlBlockPair
	{
		RTOrdDtlBlock*	_block;		///< 委托明细数据块指针
		BoostMFPtr		_file;		///< 内存映射文件智能指针
		uint64_t		_last_cap;	///< 最后容量记录

		std::shared_ptr< std::ofstream>	_fstream;	///< 文件输出流智能指针

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_OdrDtlBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
		}
	} OrdDtlBlockPair;
	typedef faster_hashmap<std::string, OrdDtlBlockPair>	OrdDtlBlockFilesMap; ///< 委托明细数据块映射表

	/*!
	 * \struct OrdQueBlockPair
	 * \brief 委托队列数据块配对结构体
	 * 
	 * \details 用于管理实时委托队列数据块的结构体，包含：
	 *          - 数据块指针：指向实际的委托队列数据块
	 *          - 文件映射：内存映射文件的智能指针
	 *          - 容量记录：记录最后的数据容量
	 *          - 文件流：用于数据写入的文件流
	 */
	typedef struct _OdrQueBlockPair
	{
		RTOrdQueBlock*	_block;		///< 委托队列数据块指针
		BoostMFPtr		_file;		///< 内存映射文件智能指针
		uint64_t		_last_cap;	///< 最后容量记录

		std::shared_ptr< std::ofstream>	_fstream;	///< 文件输出流智能指针

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_OdrQueBlockPair()
		{
			_block = NULL;
			_file = NULL;
			_last_cap = 0;
		}
	} OrdQueBlockPair;
	typedef faster_hashmap<std::string, OrdQueBlockPair>	OrdQueBlockFilesMap; ///< 委托队列数据块映射表

	RTKBlockFilesMap	_rt_min1_map;	///< 实时1分钟K线数据映射表
	RTKBlockFilesMap	_rt_min5_map;	///< 实时5分钟K线数据映射表

	TBlockFilesMap		_rt_tick_map;	///< 实时Tick数据映射表
	TransBlockFilesMap	_rt_trans_map;	///< 实时成交数据映射表
	OrdDtlBlockFilesMap	_rt_orddtl_map;	///< 实时委托明细数据映射表
	OrdQueBlockFilesMap	_rt_ordque_map;	///< 实时委托队列数据映射表

	/*!
	 * \struct HisTBlockPair
	 * \brief 历史Tick数据块配对结构体
	 * 
	 * \details 用于管理历史Tick数据的结构体，包含：
	 *          - 数据块指针：指向历史Tick数据块
	 *          - 日期：数据所属日期
	 *          - 缓冲区：数据缓冲区
	 */
	typedef struct _HisTBlockPair
	{
		HisTickBlock*	_block;		///< 历史Tick数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_HisTBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisTBlockPair;

	typedef faster_hashmap<std::string, HisTBlockPair>	HisTickBlockMap; ///< 历史Tick数据映射表

	/*!
	 * \struct HisTransBlockPair
	 * \brief 历史成交数据块配对结构体
	 * 
	 * \details 用于管理历史成交数据的结构体，包含：
	 *          - 数据块指针：指向历史成交数据块
	 *          - 日期：数据所属日期
	 *          - 缓冲区：数据缓冲区
	 */
	typedef struct _HisTransBlockPair
	{
		HisTransBlock*	_block;		///< 历史成交数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_HisTransBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisTransBlockPair;

	typedef faster_hashmap<std::string, HisTransBlockPair>	HisTransBlockMap; ///< 历史成交数据映射表

	/*!
	 * \struct HisOrdDtlBlockPair
	 * \brief 历史委托明细数据块配对结构体
	 * 
	 * \details 用于管理历史委托明细数据的结构体，包含：
	 *          - 数据块指针：指向历史委托明细数据块
	 *          - 日期：数据所属日期
	 *          - 缓冲区：数据缓冲区
	 */
	typedef struct _HisOrdDtlBlockPair
	{
		HisOrdDtlBlock*	_block;		///< 历史委托明细数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_HisOrdDtlBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisOrdDtlBlockPair;

	typedef faster_hashmap<std::string, HisOrdDtlBlockPair>	HisOrdDtlBlockMap; ///< 历史委托明细数据映射表

	/*!
	 * \struct HisOrdQueBlockPair
	 * \brief 历史委托队列数据块配对结构体
	 * 
	 * \details 用于管理历史委托队列数据的结构体，包含：
	 *          - 数据块指针：指向历史委托队列数据块
	 *          - 日期：数据所属日期
	 *          - 缓冲区：数据缓冲区
	 */
	typedef struct _HisOrdQueBlockPair
	{
		HisOrdQueBlock*	_block;		///< 历史委托队列数据块指针
		uint64_t		_date;		///< 数据日期
		std::string		_buffer;	///< 数据缓冲区

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化所有成员为默认值
		 */
		_HisOrdQueBlockPair()
		{
			_block = NULL;
			_date = 0;
			_buffer.clear();
		}
	} HisOrdQueBlockPair;

	typedef faster_hashmap<std::string, HisOrdQueBlockPair>	HisOrdQueBlockMap; ///< 历史委托队列数据映射表

	HisTickBlockMap		_his_tick_map;		///< 历史Tick数据映射表
	HisOrdDtlBlockMap	_his_orddtl_map;	///< 历史委托明细数据映射表
	HisOrdQueBlockMap	_his_ordque_map;	///< 历史委托队列数据映射表
	HisTransBlockMap	_his_trans_map;		///< 历史成交数据映射表

private:
	/*!
	 * \brief 获取实时K线数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \param period K线周期
	 * \return 实时K线数据块配对指针
	 * 
	 * 根据交易所、合约代码和周期获取对应的实时K线数据块
	 */
	RTKlineBlockPair* getRTKilneBlock(const char* exchg, const char* code, WTSKlinePeriod period);
	
	/*!
	 * \brief 获取实时Tick数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return Tick数据块配对指针
	 * 
	 * 根据交易所和合约代码获取对应的实时Tick数据块
	 */
	TickBlockPair* getRTTickBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时委托队列数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 委托队列数据块配对指针
	 * 
	 * 根据交易所和合约代码获取对应的实时委托队列数据块
	 */
	OrdQueBlockPair* getRTOrdQueBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时委托明细数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 委托明细数据块配对指针
	 * 
	 * 根据交易所和合约代码获取对应的实时委托明细数据块
	 */
	OrdDtlBlockPair* getRTOrdDtlBlock(const char* exchg, const char* code);
	
	/*!
	 * \brief 获取实时成交数据块
	 * \param exchg 交易所代码
	 * \param code 合约代码
	 * \return 成交数据块配对指针
	 * 
	 * 根据交易所和合约代码获取对应的实时成交数据块
	 */
	TransBlockPair* getRTTransBlock(const char* exchg, const char* code);

	/*!
	 * \brief 缓存期货主力合约连续K线数据
	 * \param key 缓存键值
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \return 是否缓存成功
	 * 
	 * 将期货主力合约的连续K线数据缓存到内存中
	 */
	bool	cacheIntegratedFutBars(const std::string& key, const char* stdCode, WTSKlinePeriod period);
	
	/*!
	 * \brief 缓存股票复权K线数据
	 * \param key 缓存键值
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \return 是否缓存成功
	 * 
	 * 将股票复权后的K线数据缓存到内存中
	 */
	bool	cacheAdjustedStkBars(const std::string& key, const char* stdCode, WTSKlinePeriod period);

	/*!
	 * \brief 从文件缓存历史K线数据
	 * \param key 缓存键值
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \return 是否缓存成功
	 * 
	 * 从历史数据文件中加载K线数据并缓存到内存
	 */
	bool	cacheHisBarsFromFile(const std::string& key, const char* stdCode, WTSKlinePeriod period);
	
	/*!
	 * \brief 从外部加载器缓存最终K线数据
	 * \param key 缓存键值
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \return 是否缓存成功
	 * 
	 * 通过外部数据加载器获取最终的K线数据并缓存
	 */
	bool	cacheFinalBarsFromLoader(const std::string& key, const char* stdCode, WTSKlinePeriod period);

	/*!
	 * \brief 从文件加载股票复权因子
	 * \param adjfile 复权因子文件路径
	 * \return 是否加载成功
	 * 
	 * 从指定文件加载股票的复权因子数据
	 */
	bool	loadStkAdjFactorsFromFile(const char* adjfile);
	
	/*!
	 * \brief 从外部加载器加载股票复权因子
	 * \return 是否加载成功
	 * 
	 * 通过外部数据加载器获取股票复权因子数据
	 */
	bool	loadStkAdjFactorsFromLoader();

public:
	/*!
	 * \brief 初始化数据读取器
	 * \param cfg 配置参数
	 * \param sink 数据读取器回调接口
	 * \param loader 历史数据加载器，默认为NULL
	 * 
	 * 使用配置参数初始化数据读取器，设置数据目录、缓存参数等
	 */
	virtual void init(WTSVariant* cfg, IDataReaderSink* sink, IHisDataLoader* loader = NULL) override;

	/*!
	 * \brief 分钟结束事件处理
	 * \param uDate 当前日期
	 * \param uTime 当前时间
	 * \param endTDate 结束交易日期，默认为0
	 * 
	 * 处理分钟结束事件，用于实时数据的定时更新和维护
	 */
	virtual void onMinuteEnd(uint32_t uDate, uint32_t uTime, uint32_t endTDate = 0) override;

	/*!
	 * \brief 读取Tick数据切片
	 * \param stdCode 标准合约代码
	 * \param count 读取数量
	 * \param etime 结束时间，默认为0（最新数据）
	 * \return Tick数据切片指针
	 * 
	 * 读取指定合约的Tick数据，支持历史数据和实时数据
	 */
	virtual WTSTickSlice*	readTickSlice(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取委托明细数据切片
	 * \param stdCode 标准合约代码
	 * \param count 读取数量
	 * \param etime 结束时间，默认为0（最新数据）
	 * \return 委托明细数据切片指针
	 * 
	 * 读取指定合约的Level2委托明细数据
	 */
	virtual WTSOrdDtlSlice*	readOrdDtlSlice(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取委托队列数据切片
	 * \param stdCode 标准合约代码
	 * \param count 读取数量
	 * \param etime 结束时间，默认为0（最新数据）
	 * \return 委托队列数据切片指针
	 * 
	 * 读取指定合约的Level2委托队列数据
	 */
	virtual WTSOrdQueSlice*	readOrdQueSlice(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取成交数据切片
	 * \param stdCode 标准合约代码
	 * \param count 读取数量
	 * \param etime 结束时间，默认为0（最新数据）
	 * \return 成交数据切片指针
	 * 
	 * 读取指定合约的Level2逐笔成交数据
	 */
	virtual WTSTransSlice*	readTransSlice(const char* stdCode, uint32_t count, uint64_t etime = 0) override;
	
	/*!
	 * \brief 读取K线数据切片
	 * \param stdCode 标准合约代码
	 * \param period K线周期
	 * \param count 读取数量
	 * \param etime 结束时间，默认为0（最新数据）
	 * \return K线数据切片指针
	 * 
	 * 读取指定合约的K线数据，支持多种周期（1分钟、5分钟、日线等）
	 */
	virtual WTSKlineSlice*	readKlineSlice(const char* stdCode, WTSKlinePeriod period, uint32_t count, uint64_t etime = 0) override;

	/*!
	 * \brief 获取指定日期的复权因子
	 * \param stdCode 标准合约代码
	 * \param date 指定日期，默认为0（最新）
	 * \return 复权因子值
	 * 
	 * 获取股票在指定日期的复权因子，用于价格复权计算
	 */
	virtual double getAdjFactorByDate(const char* stdCode, uint32_t date = 0) override;

private:
	std::string		_base_dir;		///< 基础数据目录路径
	IBaseDataMgr*	_base_data_mgr;	///< 基础数据管理器指针
	IHotMgr*		_hot_mgr;		///< 主力合约管理器指针

	/*!
	 * \struct BarsList
	 * \brief K线数据列表结构体
	 * 
	 * \details 用于缓存K线数据的结构体，包含：
	 *          - 交易所和合约信息
	 *          - K线周期和实时数据游标
	 *          - K线数据向量和复权因子
	 */
	typedef struct _BarsList
	{
		std::string		_exchg;			///< 交易所代码
		std::string		_code;			///< 合约代码
		WTSKlinePeriod	_period;		///< K线周期
		uint32_t		_rt_cursor;		///< 实时数据游标
		std::string		_raw_code;		///< 原始合约代码

		std::vector<WTSBarStruct>	_bars;	///< K线数据向量
		double			_factor;		///< 复权因子

		/*!
		 * \brief 构造函数
		 * 
		 * 初始化游标和因子为最大值，表示未初始化状态
		 */
		_BarsList() :_rt_cursor(UINT_MAX), _factor(DBL_MAX){}
	} BarsList;

	typedef faster_hashmap<std::string, BarsList> BarsCache;	///< K线数据缓存映射表
	BarsCache	_bars_cache;	///< K线数据缓存

	uint64_t	_last_time;		///< 最后更新时间

	/*!
	 * \struct AdjFactor
	 * \brief 复权因子结构体
	 * 
	 * \details 用于存储股票复权因子信息：
	 *          - 日期：复权因子生效日期
	 *          - 因子：复权因子数值
	 */
	typedef struct _AdjFactor
	{
		uint32_t	_date;		///< 复权因子生效日期
		double		_factor;	///< 复权因子数值
	} AdjFactor;
	typedef std::vector<AdjFactor> AdjFactorList;					///< 复权因子列表类型
	typedef faster_hashmap<std::string, AdjFactorList>	AdjFactorMap;	///< 复权因子映射表类型
	AdjFactorMap	_adj_factors;	///< 复权因子映射表

	/*!
	 * \brief 获取复权因子列表
	 * \param code 合约代码
	 * \param exchg 交易所代码
	 * \param pid 产品ID
	 * \return 复权因子列表的常量引用
	 * 
	 * 根据合约信息获取对应的复权因子列表
	 */
	const AdjFactorList& getAdjFactors(const char* code, const char* exchg, const char* pid);
	
};

NS_WTP_END